/**
 * Markdown编辑器应用
 */
export const MarkdownEditor = (function (window, undefined) {
"use strict";

// 私有变量
let converter;
let elements = {};
let state = {
    isFullscreen: false,
    currentTheme: 'light'
};

/**
 * 通用工具函数
 */
const Utils = {
    /**
     * 创建并添加CSS/JS链接
     * @param {string} url - CSS/JS文件URL
     */
    addResource: function(url, type) {
        let element;

        if (type === "css") {
            element = document.createElement("link");
            element.setAttribute("rel", "stylesheet");
            element.setAttribute("type", "text/css");
            element.setAttribute("href", url);
        } else if (type === "js") {
            element = document.createElement("script");
            element.setAttribute("type", "text/javascript");
            element.setAttribute("src", url);
        } else {
            console.error("Unsupported resource type: " + type);
            return;
        }

        document.head.appendChild(element);
    },

    /**
     * 跨浏览器兼容的事件绑定函数
     * @param {Element} elem - DOM元素
     * @param {string} type - 事件类型
     * @param {Function} handle - 回调函数
     */
    addEvent: function(elem, type, handle) {
        if (elem.addEventListener) {
            elem.addEventListener(type, handle, false);
        } else if(elem.attachEvent) {
            elem.attachEvent('on' + type, handle);
        } else {
            elem['on' + type] = handle;
        }
    },

    /**
     * 防抖函数 - 限制函数调用频率
     * @param {Function} handler - 需要防抖的函数
     * @param {number} delay - 延迟时间(ms)
     * @return {Function} 防抖处理后的函数
     */
    debounce: function(handler, delay) {
        var timer = null;
        return function() {
            var self = this,
                arg = arguments;
            clearTimeout(timer);

            timer = setTimeout(function() {
                handler.apply(self, arg);
            }, delay);
        }
    },

    /**
     * 从HTML字符串创建DOM节点
     * @param {string} template - HTML模板字符串
     * @return {Element} 创建的DOM节点
     */
    createNode: function(template) {
        var tempNode = document.createElement('div');
        tempNode.innerHTML = template;
        return tempNode.firstChild;
    },

    /**
     * 创建元素并设置属性
     * @param {string} tag - 标签名
     * @param {Object} attributes - 属性键值对
     * @param {string} [html] - 内部HTML
     * @return {Element} 创建的DOM元素
     */
    createElement: function(tag, attributes = {}, html = '') {
        const element = document.createElement(tag);

        // 设置属性
        for (const key in attributes) {
            if (attributes.hasOwnProperty(key)) {
                element.setAttribute(key, attributes[key]);
            }
        }

        // 设置内部HTML
        if (html) {
            element.innerHTML = html;
        }

        return element;
    },

    /**
     * 将元素添加到父元素
     * @param {Element} parent - 父元素
     * @param {...Element} children - 子元素列表
     */
    appendChildren: function(parent, ...children) {
        children.forEach(child => parent.appendChild(child));
    }
};

/**
 * 构建用户界面
 */
const UIBuilder = {
    /**
     * 构建编辑器UI
     * @param {Element} container - 容器元素
     */
    buildUI: function(container) {
        // 创建标题
        const title = Utils.createElement('h2', {}, 'Markdown 编辑器 (Typora 快捷键 + 代码高亮 + 暗色主题)');

        // 创建工具栏
        const toolbar = this.createToolbar();

        // 创建编辑器容器
        const editorContainer = this.createEditorContainer();

        // 创建帮助模态框
        const helpModal = this.createHelpModal();

        // 添加到容器
        Utils.appendChildren(container, title, toolbar, editorContainer, helpModal);
    },

    /**
     * 创建工具栏
     * @return {Element} 工具栏元素
     */
    createToolbar: function() {
        const toolbar = Utils.createElement('div', { 'class': 'toolbar' });

        // 左侧按钮组
        const toolbarLeft = Utils.createElement('div', { 'class': 'toolbar-left' });
        const editButton = Utils.createElement('button', {
            'id': 'edit-button',
            'class': 'toolbar-button active',
            'title': '编辑模式'
        }, '<i class="fas fa-edit"></i> 编辑');

        const previewButton = Utils.createElement('button', {
            'id': 'preview-button',
            'class': 'toolbar-button',
            'title': '预览模式'
        }, '<i class="fas fa-eye"></i> 预览');

        Utils.appendChildren(toolbarLeft, editButton, previewButton);

        // 右侧按钮组
        const toolbarRight = Utils.createElement('div', { 'class': 'toolbar-right' });
        const helpButton = Utils.createElement('button', {
            'id': 'help-button',
            'class': 'toolbar-button',
            'title': '帮助'
        }, '<i class="fas fa-question-circle"></i> 帮助');
        const themeButton = Utils.createElement('button', {
            'id': 'theme-button',
            'class': 'toolbar-button',
            'title': '切换主题'
        }, '<i class="fas fa-moon"></i> 切换主题');

        const fullscreenButton = Utils.createElement('button', {
            'id': 'fullscreen-button',
            'class': 'toolbar-button',
            'title': '全屏'
        }, '<i class="fas fa-expand"></i> 全屏');

        Utils.appendChildren(toolbarRight, helpButton, themeButton, fullscreenButton);

        // 添加按钮组到工具栏
        Utils.appendChildren(toolbar, toolbarLeft, toolbarRight);

        return toolbar;
    },

    /**
     * 创建编辑器容器
     * @return {Element} 编辑器容器元素
     */
    createEditorContainer: function() {
        const editorContainer = Utils.createElement('div', { 'class': 'editor-container' });

        const textarea = Utils.createElement('textarea', {
            'id': 'markdown-input',
            'placeholder': '输入 Markdown 语法...'
        });

        const preview = Utils.createElement('div', {
            'id': 'preview',
            'class': 'preview'
        });

        Utils.appendChildren(editorContainer, textarea, preview);

        return editorContainer;
    },

    /**
     * 创建帮助模态框
     * @return {Element} 帮助模态框元素
     */
    createHelpModal: function() {
        const helpModal = Utils.createElement('div', { 'class': 'help-modal' });
        const helpContent = Utils.createElement('div', { 'class': 'help-content' });

        const closeButton = Utils.createElement('button', { 'class': 'close-help' }, '&times;');
        const title = Utils.createElement('h3', {}, 'Markdown 语法帮助');

        // 创建帮助表格
        const helpTable = this.createHelpTable();

        Utils.appendChildren(helpContent, closeButton, title, helpTable);
        helpModal.appendChild(helpContent);

        return helpModal;
    },

    /**
     * 创建帮助表格
     * @return {Element} 帮助表格元素
     */
    createHelpTable: function() {
        const table = Utils.createElement('table');

        // 表头
        const headerRow = Utils.createElement('tr');
        headerRow.appendChild(Utils.createElement('th', {}, '语法'));
        headerRow.appendChild(Utils.createElement('th', {}, '描述'));
        headerRow.appendChild(Utils.createElement('th', {}, '快捷键'));

        // 帮助项列表
        const helpItems = [
            ['# 标题文本', '一级标题 (H1)', ''],
            ['## 标题文本', '二级标题 (H2)', ''],
            ['**文本**', '加粗文本', 'Ctrl+B'],
            ['*文本*', '斜体文本', 'Ctrl+I'],
            ['`代码`', '行内代码', 'Ctrl+Shift+M'],
            ['```<br>代码块<br>```', '代码块', 'Ctrl+Shift+K'],
            ['[链接文本](URL)', '超链接', ''],
            ['![alt 文本](图片URL)', '图片', ''],
            ['1. 列表项<br>2. 列表项', '有序列表', ''],
            ['- 列表项<br>- 列表项', '无序列表', ''],
            ['---', '水平分割线', ''],
            ['> 引用文本', '引用块', '']
        ];

        // 添加表头
        table.appendChild(headerRow);

        // 添加帮助项
        helpItems.forEach(item => {
            const row = Utils.createElement('tr');
            row.appendChild(Utils.createElement('td', {}, item[0]));
            row.appendChild(Utils.createElement('td', {}, item[1]));
            row.appendChild(Utils.createElement('td', {}, item[2]));
            table.appendChild(row);
        });

        return table;
    }
};

/**
 * 初始化编辑器
 */
function init() {
    // 使用 Utils.addResource 加载所有必要的资源
    // 先加载 CSS 资源
    Utils.addResource("/css/main.css", "css");
    Utils.addResource("/lib/highlight/11.9.0/github-dark.min.css", "css");
    Utils.addResource("/lib/font-awesome/6.4.0/all.min.css", "css");
    
    // 加载 JS 资源并设置加载完成后的回调
    loadJSResources([
        "/lib/showdown/2.1.0/showdown.min.js",
        "/lib/highlight/11.9.0/highlight.min.js"
    ], function() {
        // 构建UI
        const appContainer = document.getElementById('app-container');
        UIBuilder.buildUI(appContainer);

        // 初始化转换器
        converter = new showdown.Converter();

        // 缓存DOM元素
        cacheElements();

        // 初始化功能模块
        EditorCore.init();
        ThemeManager.init();
        ToolbarManager.init();
        HelpManager.init();
        KeyboardManager.init();

        // 设置初始内容
        setInitialContent();
    });
}

/**
 * 加载 JavaScript 资源并在全部加载完成后执行回调
 * @param {Array} jsFiles - JS 文件路径数组
 * @param {Function} callback - 所有 JS 加载完成后的回调函数
 */
function loadJSResources(jsFiles, callback) {
    let loadedCount = 0;
    const totalFiles = jsFiles.length;
    
    // 没有文件需要加载时直接执行回调
    if (totalFiles === 0) {
        callback();
        return;
    }

    // 资源加载完成时的处理函数
    function onScriptLoaded() {
        loadedCount++;
        if (loadedCount === totalFiles) {
            // 所有资源都已加载完成
            callback();
        }
    }

    // 加载每个 JS 文件
    jsFiles.forEach(file => {
        const script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", file);
        script.onload = onScriptLoaded;
        script.onerror = function() {
            console.error("无法加载 JS 文件: " + file);
            onScriptLoaded(); // 即使加载失败也继续
        };
        document.head.appendChild(script);
    });
}

/**
 * 缓存常用DOM元素引用
 */
function cacheElements() {
    elements = {
        markdownInput: document.getElementById("markdown-input"),
        preview: document.getElementById("preview"),
        themeButton: document.getElementById("theme-button"),
        editorContainer: document.querySelector(".editor-container"),
        toolbar: document.querySelector(".toolbar"),
        editButton: document.getElementById("edit-button"),
        previewButton: document.getElementById("preview-button"),
        helpButton: document.getElementById("help-button"),
        fullscreenButton: document.getElementById("fullscreen-button"),
        helpModal: document.querySelector(".help-modal"),
        closeHelp: document.querySelector(".close-help")
    };
}

/**
 * 编辑器核心功能
 */
const EditorCore = {
    init: function() {
        // 监听输入变化 (使用防抖功能优化性能)
        Utils.addEvent(
            elements.markdownInput,
            "input",
            Utils.debounce(this.renderMarkdown, 150)
        );
    },

    renderMarkdown: function() {
        const markdownText = elements.markdownInput.value;
        let html = converter.makeHtml(markdownText);
        elements.preview.innerHTML = html;
        elements.preview.querySelectorAll("pre code").forEach(block =>
            hljs.highlightElement(block)
        );
    },

    insertMarkdownSyntax: function(startTag, endTag = "", placeholder = "文本") {
        const input = elements.markdownInput;
        const start = input.selectionStart;
        const end = input.selectionEnd;
        const text = input.value;
        const selectedText = text.substring(start, end) || placeholder;
        const newText = text.substring(0, start) + startTag + selectedText + endTag + text.substring(end);

        input.value = newText;
        input.focus();
        input.setSelectionRange(start + startTag.length, start + startTag.length + selectedText.length);

        // 触发输入事件以更新预览
        var event = new Event("input");
        input.dispatchEvent(event);
    },

    setEditMode: function() {
        elements.editorContainer.classList.remove("preview-mode");
        elements.editorContainer.classList.add("edit-mode");
        elements.editButton.classList.add("active");
        elements.previewButton.classList.remove("active");
    },

    setPreviewMode: function() {
        elements.editorContainer.classList.remove("edit-mode");
        elements.editorContainer.classList.add("preview-mode");
        elements.previewButton.classList.add("active");
        elements.editButton.classList.remove("active");
    }
};

/**
 * 主题管理
 */
const ThemeManager = {
    init: function() {
        // 读取并应用上次使用的主题
        this.loadSavedTheme();

        // 绑定主题切换事件
        Utils.addEvent(elements.themeButton, "click", this.toggleTheme.bind(this));
    },

    setTheme: function(mode) {
        state.currentTheme = mode;
        document.body.classList.toggle("dark", mode === "dark");
        localStorage.setItem("theme", mode);

        // 更新主题切换按钮图标和文本
        if (mode === "dark") {
            elements.themeButton.innerHTML = '<i class="fas fa-sun"></i> 切换主题';
            elements.themeButton.setAttribute('title', '切换到亮色主题');
        } else {
            elements.themeButton.innerHTML = '<i class="fas fa-moon"></i> 切换主题';
            elements.themeButton.setAttribute('title', '切换到暗色主题');
        }
    },

    toggleTheme: function() {
        const newTheme = state.currentTheme === "dark" ? "light" : "dark";
        this.setTheme(newTheme);
    },

    loadSavedTheme: function() {
        const savedTheme = localStorage.getItem("theme") || "light";
        this.setTheme(savedTheme);
    }
};

/**
 * 工具栏管理
 */
const ToolbarManager = {
    init: function() {
        // 编辑模式按钮
        Utils.addEvent(elements.editButton, "click", EditorCore.setEditMode);

        // 预览模式按钮
        Utils.addEvent(elements.previewButton, "click", EditorCore.setPreviewMode);

        // 全屏按钮
        Utils.addEvent(elements.fullscreenButton, "click", this.toggleFullscreen.bind(this));

        // 监听全屏状态变化
        Utils.addEvent(document, "fullscreenchange", this.handleFullscreenChange.bind(this));
        Utils.addEvent(document, "webkitfullscreenchange", this.handleFullscreenChange.bind(this));
        Utils.addEvent(document, "mozfullscreenchange", this.handleFullscreenChange.bind(this));
        Utils.addEvent(document, "MSFullscreenChange", this.handleFullscreenChange.bind(this));
    },

    toggleFullscreen: function() {
        if (!document.fullscreenElement) {
            this.enterFullscreen();
        } else {
            this.exitFullscreen();
        }
    },

    enterFullscreen: function() {
        // 请求全屏
        if (elements.editorContainer.requestFullscreen) {
            elements.editorContainer.requestFullscreen();
        } else if (elements.editorContainer.mozRequestFullScreen) { // Firefox
            elements.editorContainer.mozRequestFullScreen();
        } else if (elements.editorContainer.webkitRequestFullscreen) { // Chrome, Safari, Opera
            elements.editorContainer.webkitRequestFullscreen();
        } else if (elements.editorContainer.msRequestFullscreen) { // IE/Edge
            elements.editorContainer.msRequestFullscreen();
        }

        // 更新UI
        elements.fullscreenButton.innerHTML = '<i class="fas fa-compress"></i> 退出全屏';
        elements.editorContainer.classList.add("fullscreen");
        elements.toolbar.classList.add("fullscreen");
        elements.toolbar.style.borderRadius = "0";

        // 确保在全屏模式下同时显示编辑区和预览区
        document.body.classList.add("fullscreen-mode");
        elements.editorContainer.classList.remove("edit-mode", "preview-mode");

        // 重置活动按钮状态
        elements.editButton.classList.remove("active");
        elements.previewButton.classList.remove("active");

        state.isFullscreen = true;
    },

    exitFullscreen: function() {
        // 退出全屏
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.mozCancelFullScreen) { // Firefox
            document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) { // Chrome, Safari, Opera
            document.webkitExitFullscreen();
        } else if (document.msExitFullscreen) { // IE/Edge
            document.msExitFullscreen();
        }

        this.resetFromFullscreen();
    },

    resetFromFullscreen: function() {
        // 更新UI
        elements.fullscreenButton.innerHTML = '<i class="fas fa-expand"></i> 全屏';
        elements.editorContainer.classList.remove("fullscreen");
        elements.toolbar.classList.remove("fullscreen");
        elements.toolbar.style.borderRadius = "";

        // 退出全屏模式
        document.body.classList.remove("fullscreen-mode");

        // 恢复到默认编辑模式
        elements.editorContainer.classList.add("edit-mode");
        elements.editButton.classList.add("active");

        state.isFullscreen = false;
    },

    handleFullscreenChange: function() {
        if (!document.fullscreenElement &&
            !document.webkitFullscreenElement &&
            !document.mozFullScreenElement &&
            !document.msFullscreenElement) {
            this.resetFromFullscreen();
        }
    }
};

/**
 * 帮助管理
 */
const HelpManager = {
    init: function() {
        // 帮助按钮
        Utils.addEvent(elements.helpButton, "click", this.showHelp);

        // 关闭帮助按钮
        Utils.addEvent(elements.closeHelp, "click", this.hideHelp);

        // 点击帮助面板外部关闭
        Utils.addEvent(elements.helpModal, "click", (event) => {
            if (event.target === elements.helpModal) {
                this.hideHelp();
            }
        });
    },

    showHelp: function() {
        elements.helpModal.style.display = "flex";
    },

    hideHelp: function() {
        elements.helpModal.style.display = "none";
    }
};

/**
 * 键盘快捷键管理
 */
const KeyboardManager = {
    init: function() {
        Utils.addEvent(elements.markdownInput, "keydown", this.handleKeyboardShortcuts);
    },

    handleKeyboardShortcuts: function(event) {
        // 加粗: Ctrl+B
        if (event.ctrlKey && event.key.toLowerCase() === "b") {
            event.preventDefault();
            EditorCore.insertMarkdownSyntax("**", "**");
        }

        // 斜体: Ctrl+I
        if (event.ctrlKey && event.key.toLowerCase() === "i") {
            event.preventDefault();
            EditorCore.insertMarkdownSyntax("*", "*");
        }

        // 行内代码: Ctrl+Shift+M
        if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === "m") {
            event.preventDefault();
            EditorCore.insertMarkdownSyntax("`", "`");
        }

        // 代码块: Ctrl+Shift+K
        if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === "k") {
            event.preventDefault();
            EditorCore.insertMarkdownSyntax("```\n", "\n```", "代码");
        }
    }
};

/**
 * 设置初始内容
 */
function setInitialContent() {
    elements.markdownInput.value = "# 欢迎使用 Markdown 编辑器\n\n" +
                                "**加粗**, *斜体*, `代码`, [链接](https://example.com)\n\n" +
                                "```js\nconsole.log('Hello, Markdown!');\n```";

    // 触发渲染
    var event = new Event("input");
    elements.markdownInput.dispatchEvent(event);
}

// Utils.addResource("/lib/highlight/11.9.0/github-dark.min.css", "css")
// Utils.addResource("/lib/font-awesome/6.4.0/all.min.css", "css")
// Utils.addResource("/lib/showdown/2.1.0/showdown.min.js", "js")
// Utils.addResource("/lib/highlight/11.9.0/highlight.min.js", "js")

// 公共API
return {
    init: init,
    Utils: Utils,
    UIBuilder: UIBuilder,
    EditorCore: EditorCore,
    ThemeManager: ThemeManager,
    ToolbarManager: ToolbarManager,
    HelpManager: HelpManager,
    KeyboardManager: KeyboardManager
};
}(window))

window.MarkdownEditor = MarkdownEditor;
